﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Web.Mvc;
using System.Web.Mvc.Html;

namespace CID.Web.Support
{
    public static class DropDownExtensions
    {

        /// <summary>
        /// return the items of enum paired with its descrtioption.
        /// </summary>
        /// <param name="enumeration">enumeration type to be processed.</param>
        /// <returns></returns>
        private static Dictionary<string, string> GetEnumDescriptions(this Type enumeration)
        {
            if (!enumeration.IsEnum)
                throw new ArgumentException("passed type must be of Enum type", "enumerationValue");

            Dictionary<string, string> descriptions = new Dictionary<string, string>();
            var members = enumeration.GetFields().Where(m => !m.IsSpecialName);

            foreach (MemberInfo member in members)
            {
                var attrs = member.GetCustomAttributes(typeof(DescriptionAttribute), false);
                if (attrs.Count() != 0)
                    descriptions.Add(member.Name, ((DescriptionAttribute)attrs[0]).Description);
                else
                    descriptions.Add(member.Name, member.Name);
            }
            return descriptions;
        }

        public static MvcHtmlString DropDownListForEnum<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, Type enumType, object selectedValue, object htmlAttributes)
        {
            return htmlHelper.DropDownListForEnum(expression, enumType, selectedValue, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
        }

        public static MvcHtmlString DropDownListForEnum<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, Type enumType, object selectedValue = null, IDictionary<string, object> htmlAttributes = null)
        {
            var enumItems = enumType.GetEnumDescriptions();
            return htmlHelper.DropDownListFor(expression, new SelectList(enumItems, "Key", "Value", selectedValue), "Select...", htmlAttributes.DecorateWithClass(Styling.ComboBoxClass));
        }

        public static MvcHtmlString DropDownListForEntity<TModel, TProperty, TReferencedEntityViewModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<TReferencedEntityViewModel> values, int? selectedId, object htmlAttributes)
            where TReferencedEntityViewModel : Models.INamedViewModel
        {
            return htmlHelper.DropDownListForEntity(expression, values, selectedId, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
        }

        public static MvcHtmlString DropDownListForEntity<TModel, TProperty, TReferencedEntityViewModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<TReferencedEntityViewModel> values, int? selectedId, IDictionary<string, object> htmlAttributes = null)
            where TReferencedEntityViewModel : Models.INamedViewModel
        {
            return htmlHelper.DropDownListFor(expression,
                values.Select(x => new SelectListItem() { Value = x.Id.ToString(), Text = x.Name, Selected = (x.Id == selectedId) }).ToArray(), "Select...", htmlAttributes.DecorateWithClass(Styling.ComboBoxClass));
        }
    }
}